from sqlalchemy import Column, Integer, String, create_engine
from sqlmodel import Field, SQLModel, Relationship
from conf.database import Base
from typing import List, Optional
from datetime import datetime


class Hero(Base):
    __tablename__ = 'heroes'
    id = Column(Integer, primary_key=True, index=True)
    name = Column(String, index=True)
    secret_name = Column(String)
    age = Column(Integer, nullable=True)


class HeroBase(SQLModel):
    name: str
    secret_name: str
    age: int | None = None


class HeroCreate(HeroBase):
    pass


class HeroRead(HeroBase):
    pass


# 一对多关系
# class Team(SQLModel, table=True):
#     id: Optional[int] = Field(default=None, primary_key=True)
#     name: str
#     headquarters: str
#     heroes: List["Hero"] = Relationship(back_populates="team")
#
#
# class Hero(HeroBase, table=True):
#     id: Optional[int] = Field(default=None, primary_key=True)
#     name: str
#     secret_name: str
#     age: Optional[int] = None
#     # 保持 Optional 明确可为空
#     team_id: Optional[int] = Field(default=None, foreign_key="team.id")
#     team: Optional[Team] = Relationship(back_populates="heroes")
# """
# 在这个设置中：
#     • 一个 Team 可以有多个 Heroes（一对多）
#     • 一个 Hero 属于一个 Team
# """


# 多对多关系
# 对于多对多关系，定义一个中间表：
class HeroMissionLink(SQLModel, table=True):
    """
        英雄-任务关联表模型
        用于建立英雄和任务之间的多对多关系
    """
    __tablename__ = "hero_mission_link"     # 显示指定表名

    # 定义复合主键
    hero_id: Optional[int] = Field(default=None, foreign_key="hero.id", primary_key=True)
    mission_id: Optional[int] = Field(default=None, foreign_key="mission.id", primary_key=True)

    # 记录英雄加入任务的时间
    join_time: datetime | None = None


class Team(SQLModel, table=True):
    """
        团队模型
        包含团队的基本信息与应用的一对多关系
    """
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str  # 团队名称
    headquarters: str  # 总部位置

    # 与英雄表建立一对多关系
    heroes: List["Hero"] = Relationship(back_populates="team")


class Hero(SQLModel, table=True):
    """英雄模型

    包含英雄的基本信息，与团队的多对一关系，以及与任务的多对多关系
    """
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str # 英雄名称
    secret_name: str # 秘密身份
    age: Optional[int] = None # 年龄（可选）

    # 与团队的关联
    team_id: Optional[int] = Field(default=None, foreign_key="team.id")
    team: Optional[Team] = Relationship(back_populates="heroes")

    # 与任务的多对多关系
    missions: List["Mission"] = Relationship(
        back_populates="heroes",
        link_model=HeroMissionLink
    )


class Mission(SQLModel, table=True):
    """任务模型

    包含任务的基本信息和与英雄的多对多关系
    """
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str # 任务名称
    description: Optional[str] = None

    heroes: List[Hero] = Relationship(
        back_populates="missions",
        link_model=HeroMissionLink
    )
"""
这种设置允许：
    • 一个 Hero 可以参与多个 Missions
    • 一个 Mission 可以包含多个 Heroes
"""


"""
SQLModel 的优势
    • ** 统一模型 **：使用一个模型同时进行数据库操作和 API 验证
    • ** 类型安全 **：完整的类型支持简化了编码和调试
    • ** 减少样板代码 **：更少的代码重复意味着更少的错误和更容易的维护
    • ** 高级关系 **：无缝管理复杂的关系，如一对多和多对多
    • ** 数据验证 **：开箱即用地利用 Pydantic 的验证功能
"""